<?php

namespace app\common\model;

use fast\Random;
use think\Model;
use traits\model\SoftDelete;

class Order extends Model
{

    use SoftDelete;


    // 表名
    protected $name = 'order';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    // 追加属性
    protected $append = [
//        'status_text',
//        'payment_type_text',
//        'payed_time_text',
//        'delivery_type_text',
//        'delivery_status_text',
//        'delivery_time_text',
//        'is_confirm_text'
    ];


    // type
    const TYPE_DRESSUP = "dressup"; // 装扮订单
    const TYPE_PRODUCT = "product"; // 商品订单
    const TYPE_ARTWORK = "artwork"; // 作品订单

    // status
    const STATUS_CANCEL = -1; // 已取消
    const STATUS_PENDING = 0; // 未支付
    const STATUS_PAID = 1; // 已支付
    const STATUS_CONFIRM = 2; // 已接单
    const STATUS_PROCESSING = 3; // 制作中
    const STATUS_DELIVER = 4; // 配送中
    const STATUS_FINISHED = 99; // 已完成

    // delivery_type
    const DELIVERY_TYPE_VIRTUAL = 'virtual';  //无需发货
    const DELIVERY_TYPE_MERCHANT = 'merchant';  //商家配送
    const DELIVERY_TYPE_SELF = 'self';  //自提

    // delivery_status
    const DELIVERY_STATUS_NOTHING = 0;  //未发货
    const DELIVERY_STATUS_PART = 10;  //已部分发货
    const DELIVERY_STATUS_ALL = 99;  //全部发货

    // pay_status
    const PAY_STATUS_FALSE = 0;  // 未支付
    const PAY_STATUS_TRUE = 1;  //已支付

    // order_type
    const PAYMENT_TYPE_UNPAY = "unpay"; // 未支付
    const PAYMENT_TYPE_WECHAT = "wechat"; // 微信支付
    const PAYMENT_TYPE_ALIPAY = "alipay"; // 支付宝
    const PAYMENT_TYPE_CASH = "cash"; // 现金
    const PAYMENT_TYPE_UNIPAY = "unipay"; // 银联银行卡


    public function getStatusList()
    {
        return [
            self::STATUS_CANCEL     => __('Status -1'),
            self::STATUS_PENDING    => __('Status 0'),
            self::STATUS_PAID       => __('Status 1'),
            self::STATUS_CONFIRM    => __('Status 2'),
            self::STATUS_PROCESSING => __('Status 3'),
            self::STATUS_DELIVER    => __('Status 4'),
            self::STATUS_FINISHED   => __('Status 99'),
        ];
    }

    public function getPaymentTypeList()
    {
        return [
            self::PAYMENT_TYPE_UNPAY  => __('Payment_type unpay'),
            self::PAYMENT_TYPE_WECHAT => __('Payment_type wechat'),
            self::PAYMENT_TYPE_ALIPAY => __('Payment_type alipay'),
            self::PAYMENT_TYPE_CASH   => __('Payment_type cash'),
            self::PAYMENT_TYPE_UNIPAY => __('Payment_type unipay'),
        ];
    }

    public function getDeliveryTypeList()
    {
        return [
            self::DELIVERY_TYPE_VIRTUAL  => __('Delivery_type 0'),
            self::DELIVERY_TYPE_MERCHANT => __('Delivery_type 1'),
            self::DELIVERY_TYPE_SELF     => __('Delivery_type 2')
        ];
    }

    public function getDeliveryStatusList()
    {
        return [
            self::DELIVERY_STATUS_NOTHING => __('Delivery_status 0'),
            self::DELIVERY_STATUS_PART    => __('Delivery_status 10'),
            self::DELIVERY_STATUS_ALL     => __('Delivery_status 99')
        ];
    }

    public function getIsConfirmList()
    {
        return [
            '0' => __('Is_confirm 0'),
            '1' => __('Is_confirm 1')
        ];
    }


    public function getStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
        $list = $this->getStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getPaymentTypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['payment_type']) ? $data['payment_type'] : '');
        $list = $this->getPaymentTypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getPayedTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['payed_time']) ? $data['payed_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getDeliveryTypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['delivery_type']) ? $data['delivery_type'] : '');
        $list = $this->getDeliveryTypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getDeliveryStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['delivery_status']) ? $data['delivery_status'] : '');
        $list = $this->getDeliveryStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getDeliveryTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['delivery_time']) ? $data['delivery_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getIsConfirmTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['is_confirm']) ? $data['is_confirm'] : '');
        $list = $this->getIsConfirmList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    protected function setPayedTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setDeliveryTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    /**
     * 生成唯一订单号
     * @return string
     * @throws
     */
    public static function generate_order_no(string $type = ''): string
    {
        if ($type != '') {
            $type = ucfirst($type)[0];
        }
        $order_no = $type . date('Ymd') . Random::numeric(8);
        $flag = self::where(['order_no' => $order_no])->find();
        if ($flag) {
            return self::generate_order_no($type);
        }
        return $order_no;
    }

    public function user()
    {
        return $this->belongsTo(User::class, 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }


    public function admin()
    {
        return $this->belongsTo(Admin::class, 'admin_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }

    public function items()
    {
        return $this->hasMany(OrderItem::class, 'order_id', 'id');
    }
}
